<?php
/**
 * utilWebeditorDriverSimplex
 *
 *
 * @package     util
 * @subpackage  Webeditor
 * @author      Platform Team
 */

class utilWebeditorDriverSimplex extends utilWebeditorDriverAbstract
{
    const PREFIX_OBJECT = 'oNN_';

    /**
     * 에디터 객체가 담기는 JS 변수명
     */
    protected $sEditorObjectName;

    /**
     * 인스턴스 아이디
     */
    protected $sInstanceId;

    /**
     * 에디터 라벨
     */
    protected $sLabel;

    /**
     * 에디터 내용
     */
    protected $sContents;

    /**
     * 에디터 툴바 심플타입
     */
    protected $sSimpleType;

    /**
     * 툴바 배열
     */
    protected $sToolbar;

    /**
     * 세로 사이즈
     */
    protected $sHeight;

    /**
     * 툴바 제거 여부
     */
    protected $isToolbarSimple;

    /**
     * 필수 체크 여부
     */
    protected $isRequired;

    /**
     * 추가 스크립트 구문
     */
    protected $aAddScript;

    /**
     * 언어코드
     */
    protected $sLang;

    /**
     * 메인 스크립트 URL
     */
    protected $sSrc;

    /**
     * 에디터 로드
     *
     * @param array $aConfig
     * @return string
     */
    public function load($aConfig=array())
    {
        $this->initConfig($aConfig);

        if ($this->sSimpleType) {
            $sToolbarType = 'NN.Config.toolbarType = "'.$this->sSimpleType.'";';
        }

        if ($this->sToolbar) {
            $sToolbar = 'NN.Config.toolbar = '.$this->sToolbar.';';
        }

        if ($this->isToolbarSimple) {
            $sToolbarSimple = 'NN.Config.toolbarSimple = []';
        }

        $aAddScript = $this->getAddScript();
        $sRequiredElement = $this->createEditorRequiredElement();

        $sResult = '
            <script type="text/javascript" src="'.$this->sSrc.$this->sLang.'"></script>
            <script type="text/javascript">
                NN.Config.instanceID = "'.$this->sInstanceId.'";
                NN.Config.value = "'.$this->sContents.'";
                '.$sToolbarType.'
                '.$sToolbar.'
                '.$aAddScript.'
                '.$sToolbarSimple.'

                //Editor Height
                NN.Config.height='.$this->sHeight.';

                var '.$this->sEditorObjectName.' = new NNEditor();
                '.$this->sEditorObjectName.'.build();

                if (typeof $Editor != "object") {
                    $Editor = {
                        _obj : {},

                        push : function(obj, id) {
                            this._obj[id] = obj;
                        },

                        get : function(id) {
                            return this._obj[id];
                        },

                        reset : function(id) {
                            this._obj[id].getText().value = "";
                            this._obj[id].getIFDoc().body.innerHTML = this._obj[id].Config.START_HTML;
                        },

                        contents : function(id, context) {
                            this._obj[id].getText().value = context;
                            this._obj[id].getIFDoc().body.innerHTML = this._obj[id].view.parsing(2);
                        }
                    };
                }

                $Editor.push('.$this->sEditorObjectName.', "'.$this->sInstanceId.'");
            </script>
            '.$sRequiredElement.'
        ';

        return $sResult;
    }

    /**
     * 환경설정 초기화
     * @param array $aConfig
     */
    private function initConfig($aConfig)
    {
        $this->setSrc($aConfig['src']);
        $this->setLangCode($aConfig['lang']);
        $this->setInstanceId($aConfig['id']);
        $this->setLabel($aConfig['label']);
        $this->setContents($aConfig['contents']);
        $this->setSimpleType($aConfig['simple']);
        $this->setToolbar($aConfig['toolbar']);
        $this->setToolbarSimple($aConfig['toolbarSimple']);
        $this->setHeight($aConfig['height']);
        $this->setRequired($aConfig['required']);
        $this->setAddScript($aConfig['addscript']);

        $this->setEditorObjectName();
    }

    /**
     * 메인 스크립트 URL
     */
    private function setSrc($val)
    {
        $this->sSrc = $val ? $val : 'http://editor.cafe24.com/js/nneditor.js';
    }

    /**
     * 언어코드 설정 (기본은 한국어)
     */
    private function setLangCode($val)
    {
        $this->sLang = $val ? '?c=' . strtolower($val) : '';
    }

    /**
     * 에디터 오브젝트 명 설정
     */
    private function setEditorObjectName()
    {
        $this->sEditorObjectName = self::PREFIX_OBJECT . $this->sInstanceId;
    }

    /**
     * 인스턴스 아이디 세팅
     * @param $val
     */
    private function setInstanceId($val)
    {
        $this->sInstanceId = $val ? $val : 'simplex_contents';
    }

    /**
     * 에디터 라벨
     * @param $val
     */
    private function setLabel($val)
    {
        $this->sLabel = $val ? $val : 'Contents';
    }

    /**
     * 내용 세팅
     * @param $val
     */
    private function setContents($val)
    {
        $val = $this->convertContents($val);
        $val = $this->stripScript($val);
        $val = $this->securityReplace($val);
        $val = addslashes($val);
        $val = preg_replace("/\r\n|\r|\n/", '\n', $val);

        $this->sContents = $val;
    }

    /**
     * 심플타입 설정
     * @param $val
     */
    private function setSimpleType($val)
    {
        $this->sSimpleType = $val !== false ? 'simple' : false;
    }

    /**
     * 툴바 배열 설정
     * @param $val
     */
    private function setToolbar($val)
    {
        $this->sToolbar = $val ? $val : false;
    }

    /**
     * 툴바 제거 설정
     * @param $val
     */
    private function setToolbarSimple($val)
    {
        $this->isToolbarSimple = $val === true ? true : false;
    }

    /**
     * 세로 사이즈 설정
     * @param $val
     */
    private function setHeight($val)
    {
        $this->sHeight = $val ? (int)$val : 200;
    }

    /**
     * 필수 여부 설정
     * @param $val
     */
    private function setRequired($val)
    {
        $this->isRequired = $val === true ? true : false;
    }

    /**
     * 추가 스크립트 설정
     * @param $val
     */
    private function setAddScript($val)
    {
        $this->aAddScript = !empty($val) ? $val : false;
    }

    /**
     * 추가 스크립트 반환
     */
    private function getAddScript()
    {
        if (!$this->aAddScript) return '';

        if (is_array($this->aAddScript)) {

            return implode(";\n", $this->aAddScript);

        } else {

            return $this->aAddScript;

        }
    }

    /**
     * 컨텐츠 내용을 JS 구문에 들어갈 수 있도록 알맞게 치환한다
     */
    private function convertContents($sStr)
    {
        return str_replace("'", "\'", $sStr);
    }

    /**
     * 스크립트 문을 제거한다
     */
    private function stripScript($str)
    {
        return preg_replace( "#<script(.+?)/script>#ies", '', $str);
    }

    /**
     * 보안상 치환된 문자를 재치환
     */
    private function securityReplace($text)
    {
        $text = stripslashes($text);
        $code = array(
            "/\[b\](.*?)\[\/b\]/is" => '<strong>$1</strong>',
            "/\[u\](.*?)\[\/u\]/is" => '<u>$1</u>',
            "/\[IMG\](.*?)\[\/IMG\]/is" => '<img src="$1" width="" height="" />',
            "/\[MEDIA\](.*?)\[\/MEDIA\]/is" => '',
            "/\[url\=(.*?)\](.*?)\[\/b\]/is" => "<a href='$1'>$2</a>"
        );
        $text = preg_replace_callback(array_keys($code), array($this, 'securityReplaceCallback'), $text);
        return $text;
    }

    /**
     * securityReplace 콜백 메소드
     */
    private function securityReplaceCallback($text)
    {
        if ( preg_match('/\[IMG\]/i', $text[0]) ) {
            $arr = explode('|', $text[1]);
            if ( $arr[1] > 0 ) {
                return '<img alt="" src="' . $arr[0] . '" width="' . $arr[1] . '" height= "' . $arr[2] . '" />';
            } else {
                return '<img alt="" src="' . $arr[0] . '" />';
            }
        } else if ( preg_match('/\[MEDIA\]/i', $text[0]) ) {
            $arr = explode('|', $text[1]);
            $arr[0] = str_replace('_sub_', 'src', $arr[0]);
            if ( !$arr[3] || $arr[3] == 'src' ) {
                return rawurldecode($arr[0]);
            } else {
                return '<embed src="' . $arr[0] . '" width="' . $arr[1] . '" height="' . $arr[2] . '" allowScriptAccess="always" type="application/x-shockwave-flash" allowFullScreen="true" bgcolor="#000000"></embed>';
            }
        }
    }

    /**
     * 필수 입력 체크 엘리먼트 생성
     * (동작하기 위해선 Jquery UI 패키지의 Validator 플러그인이 필요함)
     *
     * @return string
     */
    private function createEditorRequiredElement()
    {
        if (!$this->isRequired) return '';

        $sResult = '
            <input type="hidden" id="'.$this->sInstanceId.'_hidden" fw-filter="isSimplexEditorFill" fw-label="'.$this->sLabel.'" value="'.$this->sEditorObjectName.'" />
        ';

        return $sResult;
    }
}